/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 * <p>
 * https://www.renren.io
 * <p>
 * 版权所有，侵权必究！
 */

package com.theme.passport.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.theme.common.base.DateHandler;
import com.theme.common.mvc.exception.RRException;
import com.theme.common.mvc.utils.PageUtils;
import com.theme.common.mvc.utils.Query;
import com.theme.common.mvc.utils.RedisKeys;
import com.theme.common.mvc.validator.AppKeys;
import com.theme.common.mvc.validator.Assert;
import com.theme.common.office.EchartsHandler;
import com.theme.passport.dao.UserDao;
import com.theme.passport.entity.ThirdUserEntity;
import com.theme.passport.entity.UserEntity;
import com.theme.passport.entity.constant.UserReviewStatusEnum;
import com.theme.passport.entity.constant.UserVipEnum;
import com.theme.passport.form.LoginForm;
import com.theme.passport.service.ThirdUserService;
import com.theme.passport.service.UserService;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {

    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private UserService userService;

    @Autowired
    private ThirdUserService thirdUserService;

    private ValueOperations<String, String> strValueOperations;
    private HashOperations<String, String, UserEntity> userCache;

    @Override
    public UserEntity getLoginUserByToken(HttpServletRequest request) {
        String token = request.getHeader(AppKeys.TICKET_KEY);
        String userAgent = request.getHeader(AppKeys.USER_AGENT_KEY);
        logger.info("------------ token: {},userAgent: {}", token, userAgent);
        if (org.springframework.util.StringUtils.isEmpty(token)) {
            return null;
        }
        String userIdStr = strValueOperations.get(RedisKeys.concat(RedisKeys.LOGIN_APP_TOKEN_USER, token));
        logger.info("------------ getLoginUserByToken userId: {}", userIdStr);
        if (StringUtils.isEmpty(userIdStr)) {
            return null;
        }
        try {
            return this.getUserById(Long.parseLong(userIdStr));
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private UserEntity getUserById(long userId) {
        UserEntity user = userCache.get(RedisKeys.USER_CACHE_BY_ID, "" + userId);
        if (user == null) {
            UserEntity userDB = baseMapper.selectById(userId);
            if (userDB != null) {
                userCache.put(RedisKeys.USER_CACHE_BY_ID, "" + userId, userDB);
            }
            return userDB;
        }
        return user;
    }

    @Override
    public UserEntity queryByMobile(String mobile) {
        return baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("mobile", mobile));
    }

    @Override
    public long login(LoginForm form) {
        UserEntity user = queryByMobile(form.getMobile());
        Assert.isNull(user, "手机号或密码错误");

        //密码错误
        if (!user.getPassword().equals(DigestUtils.sha256Hex(form.getPassword()))) {
            throw new RRException("手机号或密码错误");
        }
        return user.getId();
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String keyword = (String) params.get("key");
        String vip = (String) params.get("vip");
        IPage<UserEntity> page = this.page(
                new Query<UserEntity>().getPage(params),
                new QueryWrapper<UserEntity>()
                        .eq(StringUtils.isNotBlank(vip), "vip", vip)
                        .eq(true, "review_status", UserReviewStatusEnum.AUDIT_PASS.getValue())
                        .like(StringUtils.isNotBlank(keyword), "nickname", keyword)

        );
        return new PageUtils(page);
    }

    @Override
    public UserEntity registerUser(UserEntity user) {
        user.setPassword(DigestUtils.sha256Hex(user.getUsername()));
        user.setStatus(1);
        user.setReviewStatus(UserReviewStatusEnum.AUDIT_PASS.getValue());
        user.setCreateTime(new Date());
        baseMapper.insert(user);

        //获取用户id:
        QueryWrapper<UserEntity> userWrapper = new QueryWrapper<>();
        userWrapper.and(wrapper -> wrapper
                .eq("origin", user.getOrigin())
                .eq("username", user.getUsername())
                .eq("nickname", user.getNickname()));

        List<UserEntity> list = userService.list(userWrapper);
        if (list == null || list.size() <=0){
            return null;
        }
        UserEntity userResult = list.get(0);
        //保存用户信息
        user.setId(userResult.getId());

        ThirdUserEntity thirdUserEntity = new ThirdUserEntity();
        BeanUtils.copyProperties(userResult, thirdUserEntity);
        thirdUserEntity.setOpenid(user.getOpenid());
        thirdUserEntity.setUserId(user.getId());
        thirdUserService.insert(thirdUserEntity);

        return user;
    }

    @Override
    public Map<String, Object> echartsList(Byte dateType, Integer status) {
        List<Map<String, Object>> userRegisterLineChart = null;
        try {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Map<String, Object> params = new HashMap<>();
            Date startTime = EchartsHandler.getStartTimeByDateType(dateType);
            Date endTime = EchartsHandler.getEndTimeByDateType(dateType);
            params.put("startTime", formatter.format(startTime));
            params.put("endTime", formatter.format(endTime));
            params.put("status", status);
            if (dateType == 1) {
                //1、按当日查询-每个小时段
                userRegisterLineChart = baseMapper.queryUserLineChartByHours(params);
            } else if (dateType == 2) {
                //2、按天查询-近七天
                userRegisterLineChart = baseMapper.queryUserLineChartByDays(params);
            } else if (dateType == 3) {
                //3、按天查询-近30天
                userRegisterLineChart = baseMapper.queryUserLineChartByMonths(params);
            } else if (dateType == 4) {
                //4、按天查询-当月每一天
                userRegisterLineChart = baseMapper.queryUserLineChartByDays(params);
            } else if (dateType == 5) {
                //5、按月查询-当年每个月
                userRegisterLineChart = baseMapper.queryUserLineChartByDays(params);
            }
            return EchartsHandler.completionDate(userRegisterLineChart, Integer.valueOf(dateType));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void updateUserById(UserEntity user) {
        baseMapper.updateById(user);
        /*UserEntity userEntity = baseMapper.selectById(user.getId());
        userCache.put(RedisKeys.USER_CACHE_BY_ID, "" + user.getId(), userEntity);*/
    }

    @Override
    public Map<String, Object> queryUserTotals(Byte dateType) {
        Map<String, Object> result = new HashMap<>();
        //用户总数量:
        QueryWrapper<UserEntity> likeWrapper = new QueryWrapper<>();
        List<UserEntity> list = userService.list(likeWrapper);
        result.put("totals",list.size());

        //用户新增数量:
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Map<String, Object> params = new HashMap<>();
        Date startTime = EchartsHandler.getStartTimeByDateType(dateType);
        Date endTime = EchartsHandler.getEndTimeByDateType(dateType);
        params.put("startTime", formatter.format(startTime));
        params.put("endTime", formatter.format(endTime));

        Integer appends = this.baseMapper.queryUserTotalByDateScope(params);
        result.put("appends",appends);
        return result;
    }

    @Override
    public UserEntity updateUserVipMonths(Long id, int months) {
        UserEntity user = userService.getById(id);
        Date vipExpiresTime = user.getVipExpiresTime();
        Integer vip = user.getVip();
        // 非会员情况
        if (vipExpiresTime == null || !vip.equals(1)){
            //从今天开始起算然后加7天时间
            Date expiresTime = DateHandler.addDateMonths(new Date(), months);
            user.setVipExpiresTime(expiresTime);
            user.setVip(UserVipEnum.ARE.getValue());
            userService.updateUserById(user);
            return user;
        }
        //如果是则直接更新时间
        Date expiresTime = DateHandler.addDateMonths(vipExpiresTime, months);
        user.setVipExpiresTime(expiresTime);
        user.setVip(UserVipEnum.ARE.getValue());
        userService.updateUserById(user);
        return user;
    }

    @Override
    public UserEntity updateUserVipDays(Long id, int days) {
        //从今天开始起算然后加7天时间
        UserEntity user = userService.getById(id);
        Date vipExpiresTime = user.getVipExpiresTime();
        Integer vip = user.getVip();
        // 非会员情况
        if (vipExpiresTime == null || !vip.equals(1)){
            //从今天开始起算然后加7天时间
            Date expiresTime = DateHandler.addDateDays(new Date(), days);
            user.setVipExpiresTime(expiresTime);
            user.setVip(UserVipEnum.ARE.getValue());
            userService.updateUserById(user);
            return user;
        }
        //如果是则直接更新时间
        Date expiresTime = DateHandler.addDateMonths(vipExpiresTime, days);
        user.setVipExpiresTime(expiresTime);
        user.setVip(UserVipEnum.ARE.getValue());
        userService.updateUserById(user);

        return user;
    }

    @Override
    public void VipExpirationCheck() {
        // 获取当前时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date todayDate = DateHandler.getStartTime(new Date());
        String todayTime = sdf.format(todayDate.getTime());
        // 查询vip过期时间大于今天的，然后设置vip为0
        QueryWrapper<UserEntity> likeWrapper = new QueryWrapper<>();
        likeWrapper.eq("vip", UserVipEnum.ARE.getValue());
        likeWrapper.le(StringUtils.isNotBlank(todayTime), "vip_expires_time", todayTime);
        List<UserEntity> list = userService.list(likeWrapper);
        //不为空 批量修改
        if (list != null && list.size() >0){
            list.forEach(userEntity -> {
                userEntity.setVip(UserVipEnum.NOT.getValue());
            });
            // 批量修改
            userService.updateBatchById(list);
        }
    }

}
